/*
 * Copyright (c) 2017 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef _SENSOR_APDS9960_H_
#define _SENSOR_APDS9960_H_

#define APDS9960_I2C_ADDRESS		0x39

#define APDS9960_ENABLE_REG		0x80
#define APDS9960_RGB_ON			0x03

#define APDS9960_ENABLE_PIEN		BIT(5)
#define APDS9960_ENABLE_PON		BIT(0)
#define APDS9960_ENABLE_AEN		BIT(1)
#define APDS9960_ENABLE_AIEN		BIT(4)
#define APDS9960_ENABLE_WEN		BIT(3)
#define APDS9960_ENABLE_ALE		(BIT(0) | BIT(1))

#define APDS9960_ENABLE_PROXY		(BIT(0) | BIT(2))
#define APDS9960_CONTROL_AGAIN		(BIT(0) | BIT(1))
#define APDS9960_CONTROL_PGAIN		(BIT(3) | BIT(2))
#define APDS9960_CONTROL_LDRIVE		(BIT(6) | BIT(7))
#define APDS9960_POWER_ON		1
#define APDS9960_ALL_BITS		(BIT(0) | BIT(1) | BIT(2) | BIT(3) |\
					BIT(4) | BIT(5) | BIT(6) | BIT(7))
#define APDS9960_ATIME_REG		0x81
#define APDS9960_ADC_VALUE		0xB6
#define APDS9960_ATIME_WRTIE		(BIT(0) | BIT(1) | BIT(2) | BIT(3) |\
					BIT(4) | BIT(5) | BIT(6) | BIT(7))
#define APDS9960_WTIME_REG		0x83

#define APDS9960_INT_AILTL_REG		0x84
#define APDS9960_INT_AILTH_REG		0x85
#define APDS9960_INT_AIHTL_REG		0x86
#define APDS9960_INT_AIHTH_REG		0x87

#define APDS9960_INT_PILT_REG		0x89
#define APDS9960_INT_PIHT_REG		0x8B

#define APDS9960_ID_REG			0x92

/* Acceptable device IDs */
#define APDS9960_ID_1			0xAB
#define APDS9960_ID_2			0x9C

#define APDS9960_STATUS_REG		0x93
#define APDS9960_STATUS_CPSAT		BIT(7)
#define APDS9960_STATUS_AINT		BIT(4)
#define APDS9960_STATUS_AVALID		BIT(0)

#define APDS9960_CDATAL_REG		0x94
#define APDS9960_CDATAH_REG		0x95

#define APDS9960_RDATAL_REG		0x96
#define APDS9960_RDATAH_REG		0x97

#define APDS9960_GDATAL_REG		0x98
#define APDS9960_GDATAH_REG		0x99

#define APDS9960_BDATAL_REG		0x9A
#define APDS9960_BDATAH_REG		0x9B

#define APDS9960_IFORCE_REG		0xE4
#define APDS9960_CICLEAR_REG		0xE6
#define APDS9960_AICLEAR_REG		0xE7

#define APDS9960_CONFIG1_REG		0x8D
#define APDS9960_CONFIG1_WLONG		BIT(1)

#define APDS9960_CONFIG2_REG		0x90
#define APDS9960_CONFIG2_CPSIEN		BIT(6)

#define APDS9960_CONFIG3_REG		0x9F

#define APDS9960_PERS_REG		0x8C
#define APDS9960_APERS_SHIFT		0
#define APDS9960_APERS_MASK		(BIT(0) | BIT(1) | BIT(2) | BIT(3))

#define APDS9960_CONTROL_REG		0x8F

/* On/Off definitions */
#define APDS9960_MODE_OFF		0
#define APDS9960_MODE_ON		1

/* Acceptable parameters for apds9960_setmode */
#define APDS9960_POWER			0
#define APDS9960_MBIENT_LIGHT		1
#define APDS9960_PROXIMITY		2
#define APDS9960_WAIT			3
#define APDS9960_AMBIENT_LIGHT_INT	4
#define APDS9960_PROXIMITY_INT		5
#define APDS9960_GESTURE		6
#define APDS9960_ALL			7

/* ALS Gain (AGAIN) values */
#define APDS9960_AGAIN_1X		0
#define APDS9960_AGAIN_4X		1
#define APDS9960_AGAIN_16X		2
#define APDS9960_AGAIN_64X		3

/* LED Drive values */
#define APDS9960_LED_DRIVE_100MA	0
#define APDS9960_LED_DRIVE_50MA		1
#define APDS9960_LED_DRIVE_25MA		2
#define APDS9960_LED_DRIVE_12_5MA	3

/* Proximity Gain (PGAIN) values */
#define APDS9960_PGAIN_1X		0
#define APDS9960_PGAIN_2X		1
#define APDS9960_PGAIN_4X		2
#define APDS9960_PGAIN_8X		3

/* Gesture Gain (GGAIN) values */
#define APDS9960_GGAIN_1X		0
#define APDS9960_GGAIN_2X		1
#define APDS9960_GGAIN_4X		2
#define APDS9960_GGAIN_8X		3

/* LED Boost values */
#define APDS9960_GLED_BOOST_100		0
#define APDS9960_GLED_BOOST_150		1
#define APDS9960_GLED_BOOST_200		2
#define APDS9960_GLED_BOOST_300		3

/* Gesture wait time values */
#define APDS9960_GWTIME_0MS		0
#define APDS9960_GWTIME_2_8MS		1
#define APDS9960_GWTIME_5_6MS		2
#define APDS9960_GWTIME_8_4MS		3
#define APDS9960_GWTIME_14_0MS		4
#define APDS9960_GWTIME_22_4MS		5
#define APDS9960_GWTIME_30_8MS		6
#define APDS9960_GWTIME_39_2MS		7

/* Default values */
#define APDS9960_DEFAULT_ATIME		219
#define APDS9960_DEFAULT_WTIME		246
#define APDS9960_DEFAULT_CONFIG1	0x60
#define APDS9960_DEFAULT_AGAIN		APDS9960_AGAIN_4X
#define APDS9960_DEFAULT_AILT		0xFFFF
#define APDS9960_DEFAULT_AIHT		0
#define APDS9960_DEFAULT_PERS		0x11
#define APDS9960_DEFAULT_CONFIG2	0x01

#define APDS9960_DEFAULT_PROX_PPULSE	0x87
#define APDS9960_DEFAULT_GESTURE_PPULSE	0x89
#define APDS9960_DEFAULT_POFFSET_UR	0
#define APDS9960_DEFAULT_POFFSET_DL	0

#define APDS9960_DEFAULT_LDRIVE		APDS9960_LED_DRIVE_100MA
#define APDS9960_DEFAULT_PGAIN		APDS9960_PGAIN_4X

#define APDS9960_DEFAULT_PILT		0
#define APDS9960_DEFAULT_PIHT		50

#define APDS9960_DEFAULT_CONFIG2	0x01
#define APDS9960_DEFAULT_CONFIG3	0
#define APDS9960_DEFAULT_GPENTH		40
#define APDS9960_DEFAULT_GEXTH		30
#define APDS9960_DEFAULT_GCONF1		0x40
#define APDS9960_DEFAULT_GGAIN		APDS9960_GGAIN_4X
#define APDS9960_DEFAULT_GLDRIVE	APDS9960_LED_DRIVE_100MA

#define APDS9960_DEFAULT_GWTIME		APDS9960_GWTIME_2_8MS
#define APDS9960_DEFAULT_GOFFSET	0
#define APDS9960_DEFAULT_GPULSE		0xC9
#define APDS9960_DEFAULT_GCONF3		0
#define APDS9960_DEFAULT_GIEN		0

/* proxy Registers */
#define APDS9960_ENABLE_PEN		BIT(0)
#define APDS9960_ENABLE_PIEN		BIT(5)

#define APDS9960_PILT_REG		0x89
#define APDS9960_PIHT_REG		0x8B

#define APDS9960_PERS_REG		0x8C
#define APDS9960_PERS_PPERS		(BIT(4) | BIT(5) | BIT(6) | BIT(7))

#define APDS9960_PPULSE_REG		0x8E
#define APDS9960_PPULSE_PLEN		(BIT(7) | BIT(6))
#define APDS9960_PPULSE_PULSE		(BIT(5) | BIT(4) | BIT(3) |\
					BIT(2) | BIT(1) | BIT(0))

#define APDS9960_CONTROL_PGAIN		(BIT(3) | BIT(2))

#define APDS9960_CONFIG2_PSIEN		BIT(7)
#define APDS9960_CONFIG2_LEDBOOST	(BIT(5) | BIT(4))

#define APDS9960_STATUS_PGSAT		BIT(6)
#define APDS9960_STATUS_PINT		BIT(5)
#define APDS9960_STATUS_PVALID		BIT(1)

#define APDS9960_PDATA_REG		0x9C
#define APDS9960_POFFSET_UR_REG		0x9D
#define APDS9960_POFFSET_DL_REG		0x9E

#define APDS9960_CONFIG3_REG		0x9F
#define APDS9960_CONFIG3_PCMP		BIT(5)
#define APDS9960_CONFIG3_PMSK_U		BIT(3)
#define APDS9960_CONFIG3_PMSK_D		BIT(2)
#define APDS9960_CONFIG3_PMSK_L		BIT(4)
#define APDS9960_CONFIG3_PMSK_R		BIT(0)

#define APDS9960_PICLEAR_REG		0xE5
#define APDS9960_PROXY_ON		0x05

/* Gesture Registers */
#define APDS9960_ENABLE_GEN		BIT(6)

#define APDS9960_GCONFIG4_REG		0xAB
#define APDS9960_GCONFIG4_GIEN		BIT(1)

#define APDS9960_GPENTH_REG		0xA0
#define APDS9960_GEXTH_REG		0xA1

#define APDS9960_GCONFIG1_REG		0xA2

#define APDS9960_GCONFIG1_GFIFOTH	(BIT(7) | BIT(6))
#define APDS9960_GCONFIG1_GEXMSK	(BIT(5) | BIT(4) | BIT(3) | BIT(2))
#define APDS9960_GCONFIG1_GEXPERS	(BIT(1) | BIT(0))

#define APDS9960_GCONFIG2_REG		0xA3
#define APDS9960_GCONFIG2_GGAIN		(BIT(6) | BIT(5))
#define APDS9960_GCONFIG2_GLDRIVE	(BIT(4) | BIT(3))
#define APDS9960_GCONFIG2_WTIME		(BIT(2) | BIT(1) | BIT(0))

#define APDS9960_STATUS_PGSAT		BIT(6)
#define APDS9960_CONFIG2_LEDBOOST	(BIT(5) | BIT(4))

#define APDS9960_GOFFSET_U_REG		0xA4
#define APDS9960_GOFFSET_D_REG		0xA5
#define APDS9960_GOFFSET_L_REG		0xA7
#define APDS9960_GOFFSET_R_REG		0xA9

#define APDS9960_GPULSE_REG		0xA6
#define APDS9960_GPULSE_GPULSE		(BIT(5) | BIT(4) | BIT(3) |\
					BIT(2) | BIT(1) | BIT(0))
#define APDS9960_GPULSE_GPLEN		(BIT(7) | BIT(6))

#define APDS9960_GCONFIG3_REG		0xAA

#define APDS9960_GCONFIG3_GDIMS		(BIT(1) | BIT(0))

#define APDS9960_GCONFIG4_GIEN		BIT(1)
#define APDS9960_GCONFIG4_GMODE		BIT(0)

#define APDS9960_GFLVL_REG		0xAE

#define APDS9960_GSTATUS_REG		0xAF
#define APDS9960_GSTATUS_GFOV		BIT(1)
#define APDS9960_GSTATUS_GVALID		BIT(0)

#define APDS9960_GFIFO_U_REG		0xFC
#define APDS9960_GFIFO_D_REG		0xFD
#define APDS9960_GFIFO_L_REG		0xFE
#define APDS9960_GFIFO_R_REG		0xFF

#define APDS9960_CONFIG1_LOWPOW		0x8D

struct apds9960_data {
	struct device *i2c;
	s16_t sample_c;
	s16_t sample_r;
	s16_t	sample_g;
	s16_t sample_b;
	s8_t pdata;
	s8_t gdata;
};

#define SYS_LOG_DOMAIN "APDS9960"
#define SYS_LOG_LEVEL CONFIG_SYS_LOG_SENSOR_LEVEL
#include <logging/sys_log.h>

#endif /* _SENSOR_APDS9960_H_*/
